package com.yuke.cloud.service.omc.controller.frontend;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.yuke.cloud.common.core.support.BaseController;
import com.yuke.cloud.common.util.PublicUtil;
import com.yuke.cloud.common.util.wrapper.WrapMapper;
import com.yuke.cloud.common.util.wrapper.Wrapper;
import com.yuke.cloud.service.api.pmc.dto.ProdSpecInfoDto;
import com.yuke.cloud.service.api.pmc.service.PmcFeignApi;
import com.yuke.cloud.service.api.uac.dto.UserInfoDto;
import com.yuke.cloud.service.api.uac.service.UacUserFeignApi;
import com.yuke.cloud.service.omc.config.Quartz;
import com.yuke.cloud.service.omc.dto.OdsBillDto;
import com.yuke.cloud.service.omc.dto.OdsBillInfoDto;
import com.yuke.cloud.service.omc.dto.OrderGoodsDto;
import com.yuke.cloud.service.omc.entity.OdsBill;
import com.yuke.cloud.service.omc.service.OdsBillService;
import com.yuke.cloud.service.omc.service.OdsOrderService;
import com.yuke.cloud.service.omc.utils.DateUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * Created by zn on 2019/12/10.
 */
@Slf4j
@Api(value = "WEB - OdsBillController", tags = "处理OdsBill相关请求", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
@RestController
@RequestMapping("/ods/bill")
public class OdsBillController extends BaseController {
    @Resource
    private OdsBillService odsBillService;
    @Resource
    private OdsOrderService odsOrderService;
    @Resource
    private OdsBillPayController odsBillPayController;
    @Resource
    private RedisTemplate redisTemplate;
    @Resource
    private UacUserFeignApi uacUserFeignApi;
    @Resource
    private PmcFeignApi pmcFeignApi;

    @PostMapping
    @ApiOperation(httpMethod = "POST", value = "新增一条记录")
    public Wrapper add(@ApiParam(name = "odsBill", value = "该数据记录的POJO") @RequestBody OdsBill odsBill) {
        odsBillService.save(odsBill);
        return WrapMapper.ok();
    }

    @DeleteMapping("/{id}")
    @ApiOperation(httpMethod = "DELETE", value = "根据id删除一条记录")
    public Wrapper delete(@ApiParam(name = "id", value = "记录id") @PathVariable Long id) {
        odsBillService.deleteById(id);
        return WrapMapper.ok();
    }

    @PutMapping
    @ApiOperation(httpMethod = "PUT", value = "修改一条记录")
    public Wrapper update(@ApiParam(name = "odsBill", value = "需要修改的内容") @RequestBody OdsBill odsBill) {
        odsBillService.update(odsBill);
        return WrapMapper.ok();
    }

    @GetMapping("/{id}")
    @ApiOperation(httpMethod = "GET", value = "根据ID获取具体信息")
    public Wrapper<OdsBill> detail(@ApiParam(name = "id", value = "记录id") @PathVariable Long id) {
        OdsBill odsBill = odsBillService.findById(id);
        return WrapMapper.ok(odsBill);
    }

    @PostMapping("/getAllOdsBill")
    @ApiOperation(httpMethod = "GET", value = "分页获取所有记录")
    public Wrapper<PageInfo<OdsBill>> list(@ApiParam(name = "page", value = "分页值", defaultValue = "0") @RequestParam(defaultValue = "0") Integer page,
                                                 @ApiParam(name = "size", value = "每分页返回的记录数", defaultValue = "0") @RequestParam(defaultValue = "0") Integer size,
                                                 @RequestBody(required = false) OdsBill odsBill) {


        PageHelper.startPage(page, size);
        Example example = new Example(OdsBill.class);
        Example.Criteria criteria = example.createCriteria();

        List<Long> userIdList = new ArrayList<>();
        if (odsBill != null && odsBill.getLoginName() != null) {
            Wrapper<List<UserInfoDto>> userInfoDto = uacUserFeignApi.getUserInfoDto(odsBill.getLoginName());
            List<UserInfoDto> userInfoDtos = userInfoDto.getResult();
            userIdList = userInfoDtos.stream().map(UserInfoDto::getUserId).collect(Collectors.toList());
        }
        if (odsBill != null) {
            if (odsBill.getBillType() != null) {
                criteria.andEqualTo("billType", odsBill.getBillType());
            }
            if (odsBill.getLoginName() != null && userIdList != null && userIdList.size() > 0) {
                criteria.andIn("userId", userIdList);
            }
            if (odsBill.getBalanceType() != null) {
                criteria.andEqualTo("balanceType", odsBill.getBalanceType());
            }
        }
        List<Long> userList = new ArrayList<>();
        List<OdsBill> odsBills = odsBillService.selectByExample(example);

        if (odsBills == null || odsBills.size() < 1) {
            return WrapMapper.error("该参数下的数据不存在");
        }
        if (odsBills != null && odsBills.size() > 0) {
            userList = odsBills.stream().map(OdsBill::getUserId).collect(Collectors.toList());
        }
        Wrapper<List<UserInfoDto>> userInfoByUserIds = uacUserFeignApi.getUserInfoByUserIds(userList);
        if (userInfoByUserIds != null && userInfoByUserIds.getCode() == 200 && userInfoByUserIds.getResult() != null) {
            List<UserInfoDto> resultUser = userInfoByUserIds.getResult();
            for (OdsBill bill : odsBills) {
                for (UserInfoDto infoDto : resultUser) {
                    if (bill.getUserId().toString().equals(infoDto.getUserId().toString())) {
                        bill.setLoginName(infoDto.getLoginName());
                    }
                }
            }
        }
        PageInfo pageInfo = new PageInfo(odsBills);
        return WrapMapper.ok(pageInfo);
    }


    @PostMapping("/recharge")
    @ApiOperation(httpMethod = "POST", value = "用户充值，新增一条记录")
    public Wrapper addBill(@ApiParam(name = "odsBill", value = "该数据记录的POJO") @RequestBody OdsBill odsBill) {
        log.info("准备进入支付系统，getUserId={}, getAmount={}", odsBill.getUserId(), odsBill.getAmount());

        if (PublicUtil.isEmpty(odsBill.getUserId()) && PublicUtil.isEmpty(odsBill.getAmount())) {
            return WrapMapper.error("支付参数错误");
        }

        double totalPay = Double.valueOf(odsBill.getAmount());
        Long billId = generateId();
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("paytype", "recharge");
        map.put("pay_bill_ids", billId);

        Object result = null;
        if (odsBill.getBillType().equals((byte) 2)) {  // 支付宝
            map.put("totalpay", totalPay / 100);
            JSONObject alipay = JSONObject.parseObject(JSON.toJSONString(map));
            // todo 调用支付接口
            log.info("调用支付接口传入参数" + alipay);
            try {
                Wrapper wrapper = odsBillPayController.billAliPay(alipay);
                log.info("调用支付接口返回参数" + wrapper);
                result = wrapper.getResult();
            } catch (Exception e) {
                log.error(e.getMessage());
                return WrapMapper.error("支付宝支付失败");
            }

        } else if (odsBill.getBillType().equals((byte) 3)) {  // 微信支付
            map.put("totalpay", odsBill.getAmount());
            JSONObject wxpay = JSONObject.parseObject(JSON.toJSONString(map));
            log.info("调用微信接口传入参数" + wxpay);
            try {
                Wrapper wrapper = odsBillPayController.billWxPay(wxpay);
                log.info("调用微信接口返回参数" + wrapper);
                result = wrapper.getResult();
            } catch (Exception e) {
                log.error(e.getMessage());
                return WrapMapper.error("微信支付失败");
            }
        }
        //获取最新的一条记录，拿账户余额balance值
        if (result == null) {
            return WrapMapper.error("支付失败");
        } else {
            OdsBill bill = odsBillService.selectLastOneByUserId(Long.valueOf(odsBill.getUserId()));
            if (bill != null && bill.getBalance() > 0) {
                //放入上次账单的余额
                odsBill.setBalance(bill.getBalance());
            } else {
                odsBill.setBalance(0);
            }
            odsBill.setBillId(billId);
            odsBill.setBalanceType((byte) 0);

            odsBillService.save(odsBill);
            String id = "recharge:" + billId;
            redisTemplate.opsForValue().set(id, odsBill, Quartz.second, TimeUnit.SECONDS);
        }
        return WrapMapper.ok(result);
    }

    @PostMapping("/consumer")
    @ApiOperation(httpMethod = "POST", value = "用户账户消费，新增一条记录")
    public Wrapper consumer(@ApiParam(name = "odsBill", value = "该数据记录的POJO") @RequestBody JSONObject json){
        log.info("准备进入账户支付系统，json={}",json);
        String orderids=json.get("pay_order_ids").toString();
        String totalpay=json.get("totalpay").toString();
        String userId=json.get("userId").toString();
        //获取最新的一条记录，拿账户余额balance值
        OdsBill bill = odsBillService.selectLastOneByUserId(Long.valueOf(userId));

        if (bill != null && bill.getBalance() > 0) {
            if (Integer.valueOf(totalpay) > bill.getBalance()) {
                log.info("账户余额不足，请充值！当前金额：{}",bill.getBalance());
                return WrapMapper.error("账户余额不足，请充值！");
            }


            //保存消费账单
            OdsBill odsBill=new OdsBill();
            odsBill.setBillId(generateId());
            odsBill.setAmount(Integer.valueOf(totalpay));
            odsBill.setUserId(Long.valueOf(userId));
            odsBill.setOrderIds(orderids);
            odsBill.setBillType((byte)0);//消费
            odsBill.setBalanceType((byte)1);//完成
            odsBill.setBalance(bill.getBalance());
            Long userid=odsBillPayController.doBillUpdate(odsBill);

            if(userid>0){
                //更新订单状态
                int num = odsBillPayController.updateOrderStatus(odsBill);
                log.info("更新订单状态:{}",num);
                return WrapMapper.ok("success");
            }
        }else{
            log.info("账户还未充值，请充值!");
            return WrapMapper.error("账户还未充值，请充值！");
        }
        return WrapMapper.error("账单保存错误！");
    }

    @PostMapping("/getOdsBill")
    @ApiOperation(httpMethod = "POST", value = "分页获取所有记录")
    public Wrapper<PageInfo<OdsBill>>listOdsBill(@RequestBody(required = false) JSONObject json){
        System.out.println(json);
        OdsBill odsBill = JSON.toJavaObject(json,OdsBill.class);
        System.out.println(odsBill);

        Integer page = 0;//
        if (PublicUtil.isNotEmpty(json.getInteger("page"))){
            page = json.getInteger("page");
        }// ;
        Integer size = 10;//
        if (PublicUtil.isNotEmpty(json.getInteger("size"))){
            page = json.getInteger("size");
        }// ;

        PageHelper.startPage(page,size);
        List<OdsBill> list= new ArrayList<>();
        if(odsBill!=null){
            Example example=new Example(OdsBill.class);
            Example.Criteria criteria=example.createCriteria();
            example.setOrderByClause("create_time desc");
            if (odsBill.getBillType() != null ){
                criteria.andEqualTo("billType",odsBill.getBillType());
            }
           if (odsBill.getUserId() != null){
               criteria.andEqualTo("userId",odsBill.getUserId());
           }
            if (odsBill.getBalanceType()!=null){
                criteria.andEqualTo("balanceType", odsBill.getBalanceType());
            }
            if (odsBill.getCreateTime() != null) {
                criteria.andCondition(" UNIX_TIMESTAMP(create_time)>=" + DateUtil.monthTimeBeginInMillis(odsBill.getCreateTime()) / 1000);
                criteria.andCondition(" UNIX_TIMESTAMP(create_time)<=" + DateUtil.monthTimeEndInMillis(odsBill.getCreateTime()) / 1000);

            }
            list = odsBillService.selectByExample(example);
        } else {
            list = odsBillService.findAll();
        }

        PageInfo pageInfo = new PageInfo(list);
        return WrapMapper.ok(pageInfo);
    }

    @GetMapping("/getDetail/{id}")
    @ApiOperation(httpMethod = "GET", value = "根据ID获取具体信息")
    public Wrapper<OdsBillDto> getDetail(@ApiParam(name = "id", value = "记录id") @PathVariable Long id) {
        OdsBillDto odsBillDto = new OdsBillDto();
        OdsBill odsBill = odsBillService.findById(id);
        if (odsBill != null) {
            BeanUtils.copyProperties(odsBill, odsBillDto);
            List<OrderGoodsDto> orderGoodsDtos = new ArrayList<>();
            if (odsBill.getBillType().equals((byte) 0)) {
                List<Long> orderList = Arrays.asList(odsBill.getOrderIds().split(",")).stream().map(s -> Long.parseLong(s.trim())).collect(Collectors.toList());

                //获得订单所包含的商品
                List<Map> OdsOrderGoodsList = odsOrderService.getgoods(orderList);

                //获得商品ID,specIdList
                List<Long> specIdList = new ArrayList<>();
                for (Map m : OdsOrderGoodsList) {
                    specIdList.add(Long.parseLong(m.get("spec_id").toString()));
                }

                //获得商品信息（名称）
                List<ProdSpecInfoDto> specNameList = pmcFeignApi.getSpecDtosBySpecIds(specIdList);
                for (Map map : OdsOrderGoodsList) {

                    for (ProdSpecInfoDto prodSpecInfoDto : specNameList) {
                        if (map.get("spec_id").toString().equals(prodSpecInfoDto.getSpecId().toString())) {

                            OrderGoodsDto orderGoodsDto = new OrderGoodsDto();
                            orderGoodsDto.setSpecId(prodSpecInfoDto.getSpecId());
                            orderGoodsDto.setGoodsNum(Integer.valueOf(map.get("goods_num").toString()));
                            orderGoodsDto.setSpecName(prodSpecInfoDto.getSpecName());
                            orderGoodsDtos.add(orderGoodsDto);
                        }

                    }

                }
                odsBillDto.setOdsOrderGoodsList(orderGoodsDtos);
            }
        }


        return WrapMapper.ok(odsBillDto);
    }

    @PostMapping("/getTotalBill")
    public Wrapper<OdsBillInfoDto> getTotalBill(@RequestBody(required = false) OdsBillInfoDto odsBillInfoDto) {
        OdsBillInfoDto totalBill = odsBillService.getTotalBill(odsBillInfoDto);
        if (totalBill == null) {
            return WrapMapper.error("无此参数数据");
        }
        return WrapMapper.ok(totalBill);
    }

    @PostMapping("/getLastBill")
    public Wrapper selectLastOneByUserId(@RequestBody(required = false) OdsBill bill){
        OdsBill odsBill = odsBillService.selectLastOneByUserId(bill.getUserId());
        if (PublicUtil.isNotEmpty(odsBill)){
            return WrapMapper.ok(odsBill.getBalance());
        }
        return WrapMapper.ok(0);
    }
}
